﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows.Data;
using Eniux.Framework.Infrastructure.Properties;

namespace Eniux.Framework.Infrastructure.core
{
    public class ValueConverter<TSource, TTarget> : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value != BindingOperations.DisconnectedSource)
            {
                if ((TSource)value != null || value == null && !typeof(TSource).IsValueType)
                {
                    if (targetType.IsAssignableFrom(typeof(TTarget)))
                    {
                        return this.Convert((TSource)value, parameter, culture);
                    }
                    else
                    {
                        throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resources.Error_TargetNotExtendingType, typeof(TTarget).FullName));
                    }
                }
                else
                {
                    throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Error_ValueNotOfType, typeof(TSource).FullName));
                }
            }
            else
            {
                return value;
            }
        }

        protected virtual TTarget Convert(TSource value, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, Resources.Error_ConverterFunctionNotDefined, "Convert"));
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if ((TTarget)value!= null || value == null && !typeof(TTarget).IsValueType)
            {
                if (targetType.IsAssignableFrom(typeof(TSource)))
                {
                    return this.ConvertBack((TTarget)value, parameter, culture);
                }
                else
                {
                    throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resources.Error_TargetNotExtendingType, typeof(TSource).FullName));
                }
            }
            else
            {
                throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Resources.Error_ValueNotOfType, typeof(TTarget).FullName));
            }
        }

        protected virtual TSource ConvertBack(TTarget value, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, Resources.Error_ConverterFunctionNotDefined, "ConvertBack"));
        }
    }

}
